package com.suxin.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;

/**
 * @Classname NettyServer
 * @Description [ TODO ]
 * @Author Tang
 * @Date 2021/1/2 22:43
 * @Created by ASUS
 */
public class NettyServer {

    public static void main(String[] args) throws Exception {

        /**
         * 创建两个线程组 bossGroup 和 workerGroup
         * bossGroup负责处理连接请求，
         * workerGroup处理业务
         * 两个都是无限循环
         */
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup(4);
        try {
            // 创建服务器端的启动参数，配置参数
            ServerBootstrap bootstrap = new ServerBootstrap();

            bootstrap // 设置两个线程组
                    .group(bossGroup, workerGroup)
                    // 使用 NioServerSocketChannel 作为服务器的通道实现
                    .channel(NioServerSocketChannel.class)
                    // 设置线程队列得到连接数
                    .option(ChannelOption.SO_BACKLOG, 128)
                    // 设置保持活动连接状态
                    .childOption(ChannelOption.SO_KEEPALIVE, true)
                    // 给我们的workerGroup的EventLoop对应的管道设置处理器
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        // 创建一个通道测试对象，给pipeline 设置处理器
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
//                            System.out.println("hashCode:--->" + socketChannel.hashCode());
                            socketChannel
                                    .pipeline()
                                    .addLast(new NettyServerHandler());
                        }
                    });

            System.out.println("...服务器 is ready ...");

            // 绑定一个端口并且同步，生成了一个channelFuture 对象
            // 启动服务器(并绑定端口)
            ChannelFuture future = bootstrap.bind(9000).sync();
            // 添加监听器
            future.addListener(future1 -> System.out.println("绑定端口操作完成！" + future1.isSuccess()));

            // 对关闭通道进行监听
            future.channel().closeFuture().sync();

        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

}